import {NtkoWebOffice} from "./NtkoWebOffice";
import {WpsWebOffice} from "./WpsWebOffice";
import {ZhuoZhengWebOffice} from "./ZhuoZhengWebOffice";
import {YozoWebOffice} from "./YozoWebOffice";
import {Dictionary} from "./types/Types";
import {WebOfficeInterface} from "./types/WebOfficeInterface";

let webOfficeImplMap: Dictionary = {
    "ntko": function (wrapperId: string, options: Dictionary) {
        return new NtkoWebOffice(wrapperId, options);
    },
    "wps":function (wrapperId:string,options:Dictionary) {
        return new WpsWebOffice(wrapperId,options);
    },
    "pageoffice":function (wrapperId:string,options:Dictionary) {
        return new ZhuoZhengWebOffice(wrapperId,options);
    },
    "yozo":function (wrapperId:string,options:Dictionary) {
        return new YozoWebOffice(wrapperId,options);
    }
}
class WebOffice implements WebOfficeInterface{
    private _realObj:WebOfficeInterface;
    _ready:boolean=false;
    init(wrapperId:string,options:Dictionary):Promise<any>{
        const that=this;
        that._ready=false;
        return new Promise<any>(function (resolve,reject) {
            try {
                //延迟几十毫秒再初始化，让浏览器计算并渲染完界面布局与样式
                setTimeout(()=>{
                    const wrapperEle: HTMLElement | null = document.getElementById(wrapperId);
                    if (wrapperEle == null)
                        throw new Error("id为" + wrapperId + "的元素不存在!");
                    const childNodes = wrapperEle.childNodes;
                    for(let i = childNodes .length - 1; i >= 0; i--) {
                        wrapperEle.removeChild(childNodes[i]);
                    }
                    that._showLoading(wrapperEle,options.serverPage);
                    that._realObj = webOfficeImplMap[options.pluginType](wrapperId, options);
                    let tryCount=0;
                    const intervalControl=setInterval(function () {
                        if(that._realObj._ready){
                            that._ready=true;
                            clearInterval(intervalControl);
                            that._hideLoading();
                            that.show();
                            resolve({errorCode: '0', errorMessage: '',result:that});
                        }
                        //尝试10分钟如果还没有初始化完成，则认为失败
                        if (tryCount > 6000) {
                            clearInterval(intervalControl);
                            reject({errorCode: '-1', errorMessage: '控件初始化失败，请联系管理员！'});
                        }
                        tryCount++;
                    }, 100);
                },50);
            } catch (e) {
                reject({errorCode: '-1', errorMessage: e});
            }

        }).catch(function (reason) {
            return reason;
        });
    }

    public _showLoading(wrapperEle:HTMLElement,serverPage:string){
        const loadingNodeStr='<div id="office-loading" style="width: 100%;height: '+wrapperEle.offsetHeight+'px;background-color: #e6e6e6;text-align: center;">' +
            '<div style="display:block;margin:auto;width: 220px;height: 19px;background: url('+serverPage+'/images/loading.gif)  no-repeat bottom center;padding-top: '+((wrapperEle.clientHeight-19)/2)+'px;"></div></div>'
        wrapperEle.insertAdjacentHTML('beforeend',loadingNodeStr);
    }

    public _hideLoading(){
        const loadingEle=document.getElementById("office-loading");
        if (loadingEle && loadingEle.parentNode)
            loadingEle.parentNode.removeChild(loadingEle);
    }

    public acceptAllRevisions(): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.acceptAllRevisions();
    }

    public getBookmark(name:string):any{
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.getBookmark(name);
    }

    public addBookmark(name: string): any {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.addBookmark(name);
    }

    public createFile(): Promise<any> {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.createFile();
    }

    public deleteBookmark(name: string): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.deleteBookmark(name);
    }

    public enableToolbars(enable: boolean): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        this._realObj.enableToolbars(enable);
    }

    public getAllBookmarkValue(): Object {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.getAllBookmarkValue();
    }

    public getBookmarkValue(name: string): string|undefined {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.getBookmarkValue(name);
    }

    public importFile(): Promise<any> {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.importFile();
    }

    public isBookmarkExists(name: string): boolean {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.isBookmarkExists(name);
    }

    public locateBookmark(name: string): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.locateBookmark(name);
    }

    public openLocalFile(filePath: string, readOnly: boolean): Promise<any> {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.openLocalFile(filePath,readOnly);
    }

    public openRemoteFile(url: string, readOnly: boolean): Promise<any> {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.openRemoteFile(url,readOnly);
    }

    public print(): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.print();
    }

    public rejectAllRevisions(): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.rejectAllRevisions();
    }

    public saveAs(fileName?:string): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        this._realObj.saveAs(fileName);
    }

    public saveToUrl(tempUrl?: string): Promise<any> {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.saveToUrl(tempUrl);
    }


    saveDataRange(): Promise<any> {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.saveDataRange();
    }

    webSave(): Promise<any> {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.webSave();
    }

    public setBookmarkValue(name: string, value: string | undefined): void {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.setBookmarkValue(name, value);
    }

    public showRevisions(show: boolean = true): void {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.showRevisions(show);
    }

    public trackRevisions(enable: boolean): void {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.trackRevisions(enable);
    }

    public officeApp(): any {
        if (this._realObj == null || this._realObj.officeApp() == null)
            throw new Error("控件未初始化！");
        return this._realObj.officeApp();
    }

    public pluginObj(): any {
        if (this._realObj == null || this._realObj.pluginObj() == null)
            throw new Error("控件未初始化！");
        return this._realObj.pluginObj();
    }

    public activeDocument(): any {
        if (this._realObj == null || this._realObj.activeDocument() == null)
            throw new Error("控件未初始化！");
        return this._realObj.activeDocument();
    }

    public getCellText(tableIndex: number, rowIndex: number, cellIndex: number): string | undefined {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.getCellText(tableIndex, rowIndex, cellIndex);
    }

    public setCellText(tableIndex: number, rowIndex: number, cellIndex: number, text: string): void {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        this._realObj.setCellText(tableIndex,rowIndex,cellIndex,text);
    }
    public runMacro(method:string,command?:string):any{
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.runMacro(method,command);
    }


    public insertDocumentFromUrl(documentUrl: string): Promise<boolean> {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.insertDocumentFromUrl(documentUrl);
    }

    public insertImage(imageUrl: string, pageNo?: number, left?: number, top?: number, width?: number, height?: number): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.insertImage(imageUrl,pageNo,left,top,width,height);
    }

    public addWordImageWaterMark(imagePath: string, left?: number, top?: number, width?: number, height?: number, rotation?: number): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.addWordImageWaterMark(imagePath,left,top,width,height,rotation);
    }

    public addWordTextWaterMark(text: string, left?: number, top?: number,fontFamily?: string, fontSize?: number,color?: number, width?: number, height?: number, rotation?: number, percent?: number): void {
        if(!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.addWordTextWaterMark(text, left, top, fontFamily, fontSize, color, width, height, rotation, percent);
    }

    public show(): void {
        this._realObj.show();
    }

    public hide(): void {
        this._realObj.hide();
    }

    public executeWithWriteable(func: Function): any {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        return this._realObj.executeWithWriteable(func);
    }

    printPreview(): void {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        this._realObj.printPreview();
    }

    closePrintPreview(): void {
        if (!this._realObj._ready)
            throw new Error("控件未初始化！");
        this._realObj.closePrintPreview();
    }
}

module.exports = new WebOffice();